package cn.com.chengq.oa;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.security.SecureClassLoader;
import java.util.Enumeration;

public class SalaryJarClassLoader extends URLClassLoader {


    public SalaryJarClassLoader(URL[] urls) {
        super(urls);
    }

    /**
     * 打破双亲委派机制，首先从类加载器本身的路径中加载。
     * @param name
     * @param resolve
     * @return
     * @throws ClassNotFoundException
     */
//    @Override
//    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
//        // First, check if the class has already been loaded
//        Class<?> c = findLoadedClass(name);
//
//        // 首先从该加载器的类路径中加载。
//        if (null == c) {
//            try {
//                c = this.findClass(name);
//            } catch (ClassNotFoundException ex) {
//
//            }
//        }
//
//        // 如果加载不到，再使用父类加载器加载。
//        if (null == c) {
//           c = this.getParent().loadClass(name);
//        }
//
//        return c;
//    }

    /**
     * 需要实现从*.myclass文件中加载类
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
//    @Override
//    protected Class<?> findClass(String name) throws ClassNotFoundException {
//        System.out.println("重新加载类： " + name);
//        byte[] b = loadClassData(name);
//        if (b == null || b.length == 0) {
//            // throw new ClassNotFoundException(name);
//            return null;
//        }
//        return defineClass(name, b, 0 , b.length);
//    }

    private byte[] loadClassData(String name) {
        byte[] buffer = new byte[1024];
        //String classPath = name.replace(".", "/").concat(".class");
        //String urlStr = String.format("jar:%s!/%s", jarFile, classPath);
        // System.out.println(urlStr);
        ByteArrayOutputStream baos = null;
        InputStream is = null;

        byte[] result = null;
        try {
            URL url = new URL("");
            URLConnection urlConnection = url.openConnection();
            // 取消缓存
            urlConnection.setUseCaches(false);
            is = urlConnection.getInputStream();

            // 如果该class文件之前是几个变换的，这时就可以添加反变换逻辑恢复到正常的
            // class文件格式。然后将正常格式byte数组传递个defineClass函数。
            // 这个过程就是java代码的混淆和反混淆
            baos = new ByteArrayOutputStream();
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            result = baos.toByteArray();
        } catch (Exception e) {
            // new ClassNotFoundException(name, e);
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != baos) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return result;
    }

}
